﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Device.Location;
using Microsoft.Phone.Reactive;
using Microsoft.Phone.Controls.Maps.Platform;
using HalloJSON.Maps;
using Microsoft.Phone.Controls.Maps;
using HalloJSON.CommenData;
using Newtonsoft.Json; 

namespace HalloJSON
{
    public partial class MainPage : PhoneApplicationPage
    {
        GeoCoordinateWatcher gcw;
        RootObject rootObject;
        // Constructor
        public MainPage()
        {


            // Set the data context of the listbox control to the sample data
            WebClient webClient = new WebClient();
            webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
            webClient.DownloadStringAsync(new Uri(string.Format("https://kunden.multicity-carsharing.de/kundenbuchung/hal2ajax_process.php?zoom=10&lng1=&lat1=&lng2=&lat2=&stadtCache=&mapstation_id=&mapstadt_id=&verwaltungfirma=&centerLng=13.382322739257802&centerLat=52.50734843957503&searchmode=buchanfrage&with_staedte=false&buchungsanfrage=N&lat=52.50734843957503&lng=13.382322739257802&instant_access=J&open_end=J&objectname=multicitymarker&ignore_virtual_stations=J&before=null&after=null&ajxmod=hal2map&callee=getMarker")));

          
        }
        void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            List<Pushpin> pushpins = new List<Pushpin>();
            if (!string.IsNullOrEmpty(e.Result))
            {
                rootObject = new RootObject();
                var readObject = JsonConvert.DeserializeObject<RootObject>(e.Result);
                rootObject = readObject;

                for (int count = 0; count < rootObject.marker.Count; count++)
          {
              var car = rootObject.marker[count];
              var loc = new GeoCoordinate(rootObject.marker[count].lat, rootObject.marker[count].lng);
              var kName = StringTool.GetKName(StringTool.TakeOffString(HttpUtility.HtmlDecode(rootObject.marker[count].hal2option.tooltip)));
              var typeName = StringTool.GetTypeName(StringTool.TakeOffString(HttpUtility.HtmlDecode(rootObject.marker[count].hal2option.tooltip)));
              var id = rootObject.marker[count].hal2option.id;
              Pushpin pin = new Pushpin();
              pin.Background = new SolidColorBrush(Colors.Blue);
              pin.Location = loc;
              pin.Content = kName;
              pin.DataContext = id;
              pin.ContentTemplate = this.Resources["MarkerTemplate"] as DataTemplate;
              pushpins.Add(pin);
          }

                InitializeComponent();
                if (pushpins != null)
                {
                    var clusterer = new PushpinClusterer(map, pushpins, this.Resources["ClusterTemplate"] as DataTemplate);
                    map.MouseLeftButtonUp += new MouseButtonEventHandler(Map_MouseLeftButtonUp);
                }
            }
           
        }

        private void Map_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            var fe = e.OriginalSource as FrameworkElement;
            if (fe.DataContext is string)
            {
                itemList.ItemsSource = new List<string>() { (string)fe.DataContext };
            }

            if (fe.DataContext is IEnumerable<object>)
            {
                itemList.ItemsSource = (fe.DataContext as IEnumerable<object>).Cast<string>();
            }
        }


        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            if (gcw == null)
                gcw = new GeoCoordinateWatcher();

            gcw.Start();
            showGeoPoint();
          //  ShowGeoLocation();
        }

        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedFrom(e);

            if (gcw != null)
                gcw.Stop();
        }

        // Handle selection changed on ListBox
        private void MainListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // If selected index is -1 (no selection) do nothing
            // if (MainListBox.SelectedIndex == -1)
            //     return;

            // Navigate to the new page
            //  NavigationService.Navigate(new Uri("/DetailsPage.xaml?selectedItem=" + MainListBox.SelectedIndex, UriKind.Relative));

            // Reset selected index to -1 (no selection)
            //  MainListBox.SelectedIndex = -1;
        }

        // Load data for the ViewModel Items
        private void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            if (!App.ViewModel.IsDataLoaded)
            {
                App.ViewModel.LoadData();
            }
        }

        private void showGeoPoint() 
        {
           // var clusterer = new PushpinClusterer (map, pins, this.Resources["ClusterTemplate"] as DataTemplate);

        }


        public static GeoCoordinate ToCoordinate( float latitude, float longitude)
        {
            return new GeoCoordinate(latitude, longitude);
        } 

        private void buttonZoomIn_Click(object sender, RoutedEventArgs e)
        {
            double zoom;
            zoom = map.ZoomLevel;
            map.ZoomLevel = ++zoom;
        }

        private void buttonZoomOut_Click(object sender, RoutedEventArgs e)
        {
            double zoom;
            zoom = map.ZoomLevel;
            map.ZoomLevel = --zoom;
        }


        public void ShowGeoLocation()  
        {  
            var statusChanges = from statusChanged in gcw.GetStatusChangedEventStream()  
                                where statusChanged.Status == GeoPositionStatus.Ready  
                                select statusChanged;  
 
            var positionChanges = from s in statusChanges  
                                  from position in gcw.GetPositionChangedEventStream()  
                                  select position.Position;  
 
            var positions = from position in positionChanges  
                            where position.Location.HorizontalAccuracy <= 100  
                            select position;  
 
        
            /*   positions.Take(1).Subscribe(firstLocationFix =>  
                {  
                    textBlock1.Text = string.Format("{0},{1}" 
                                           , firstLocationFix.Location.Latitude  
                                           , firstLocationFix.Location.Longitude  
                                           );  
                }  
            );*/

        }
    }

    public static class Helpers
    {
        public static IObservable<GeoPositionStatusChangedEventArgs> GetStatusChangedEventStream(this GeoCoordinateWatcher watcher)
        {
            return Observable.Create<GeoPositionStatusChangedEventArgs>(observer =>
            {
                EventHandler<GeoPositionStatusChangedEventArgs> handler = (s, e) =>
                {
                    observer.OnNext(e);
                };
                watcher.StatusChanged += handler;
                return () => { watcher.StatusChanged -= handler; };
            }
            );
        }

        public static IObservable<GeoPositionChangedEventArgs<GeoCoordinate>> GetPositionChangedEventStream(this GeoCoordinateWatcher watcher)
        {
            return Observable.Create<GeoPositionChangedEventArgs<GeoCoordinate>>(observable =>
            {
                EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>> handler = (s, e) =>
                {
                    observable.OnNext(e);
                };
                watcher.PositionChanged += handler;
                return () => { watcher.PositionChanged -= handler; };
            }
            );
        }
    }  
}